import asyncio
import os
import tomllib
from json import dumps
from pathlib import Path

from fastapi import APIRouter, Body, HTTPException
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse

from services.agent_service import TaskManager
from app.config import config as app_config
from schemas.agent_schemas import ConfigData

router = APIRouter(prefix="/execution",tags=["execution"])
task_manager = TaskManager()

def get_project_root() -> Path:
    """Get the project root directory"""
    return Path(__file__).resolve().parent.parent.parent


PROJECT_ROOT = get_project_root()
WORKSPACE_ROOT = PROJECT_ROOT / "workspace"

@router.post("/download/{task_id}")
async def download_file(task_id: str, file_path: str = Body(..., embed=True)):
    # 构建完整的文件路径
    full_path = WORKSPACE_ROOT / task_id / file_path
    
    if not full_path.exists():
        raise HTTPException(status_code=404, detail="File not found")
    
    # 确保文件路径不会超出工作目录范围
    if not str(full_path).startswith(str(WORKSPACE_ROOT / task_id)):
        raise HTTPException(status_code=403, detail="Access denied")

    return FileResponse(str(full_path), filename=os.path.basename(file_path))

@router.get("/{task_id}/files")
def get_files(task_id: str):
    task_dir = WORKSPACE_ROOT / task_id
    if not task_dir.exists():
        raise HTTPException(status_code=404, detail="Directory not found")
    
    files = []
    for file_name in os.listdir(task_dir):
        file_path = task_dir / file_name
        files.append({
            "id": task_id,  # 使用task_id作为文件id
            "name": file_name,
            "type": "file",  # 或者可以根据文件扩展名判断类型
            "size": os.path.getsize(file_path)  # 获取文件大小（字节）
        })
    
    return {'files': files}


@router.post("/tasks")
async def create_task(prompt: str = Body(..., embed=True)):
    task = task_manager.create_task(prompt)
    append_fileSave_prompt = f"""\n 
    create a result file under the {task.id} directory.
    If the {task.id} directory does not exist, 
    use the file_saver tool to create the directory and the initial file with the path {task.id}/fileName.
    """
    prompt = prompt + append_fileSave_prompt
    asyncio.create_task(task_manager.run_task(task.id, prompt))
    return {"task_id": task.id}

@router.get("/tasks/{task_id}/events")
async def task_events(task_id: str):
    async def event_generator():
        if task_id not in task_manager.queues:
            yield f"event: error\ndata: {dumps({'message': 'Task not found'})}\n\n"
            return

        queue = task_manager.queues[task_id]

        task = task_manager.tasks.get(task_id)
        if task:
            yield f"event: status\ndata: {dumps({'type': 'status', 'status': task.status, 'steps': task.steps})}\n\n"

        while True:
            try:
                event = await queue.get()
                formatted_event = dumps(event)

                yield ": heartbeat\n\n"

                if event["type"] == "complete":
                    yield f"event: complete\ndata: {formatted_event}\n\n"
                    break
                elif event["type"] == "error":
                    yield f"event: error\ndata: {formatted_event}\n\n"
                    break
                elif event["type"] == "step":
                    task = task_manager.tasks.get(task_id)
                    if task:
                        yield f"event: status\ndata: {dumps({'type': 'status', 'status': task.status, 'steps': task.steps})}\n\n"
                    yield f"event: {event['type']}\ndata: {formatted_event}\n\n"
                elif event["type"] in ["think", "tool", "act", "run"]:
                    yield f"event: {event['type']}\ndata: {formatted_event}\n\n"
                else:
                    yield f"event: {event['type']}\ndata: {formatted_event}\n\n"

            except asyncio.CancelledError:
                print(f"Client disconnected for task {task_id}")
                break
            except Exception as e:
                print(f"Error in event stream: {str(e)}")
                yield f"event: error\ndata: {dumps({'message': str(e)})}\n\n"
                break

    return StreamingResponse(
        event_generator(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no",
        },
    )


@router.get("/config/status")
async def check_config_status():
    config_path = Path(__file__).parent.parent.parent / "config" / "config.toml"
   
    if config_path.exists():
        try:
            # 读取配置文件
            with open(config_path, "rb") as f:
                config_dict = tomllib.load(f)
            
            # 提取各部分配置
            llm_config = config_dict.get("llm", {})
            browser_config = config_dict.get("browser", {})
            search_config = config_dict.get("search", {})
            
            # 处理browser.proxy特殊结构
            proxy_config = None
            if browser_config and "proxy" in browser_config:
                proxy_config = browser_config.pop("proxy")
            
            # 构建返回数据
            result = {
                "status": "exists",
                "config": {
                    "llm": llm_config if llm_config else None,
                    "browser": browser_config if browser_config else None,
                    "search": search_config if search_config else None
                }
            }
            
            # 如果有代理配置，添加到browser下
            if browser_config and proxy_config:
                result["config"]["browser"]["proxy"] = proxy_config
            
            return result
        except Exception as e:
            return {"status": "error", "message": str(e)}
    else:
        raise HTTPException(status_code=404,detail="请确保config.toml路径正确.")

@router.post("/config/save")
async def save_config(config_data: ConfigData = Body(...)):
    try:
        config_dir = Path(__file__).parent.parent.parent / "config"
        config_dir.mkdir(exist_ok=True)
        config_path = config_dir / "config.toml"
        
        toml_content = ""
        
        # 处理 LLM 配置
        if config_data.llm:
            toml_content += "# Global LLM configuration\n[llm]\n"
            llm_dict = config_data.llm.dict(exclude_none=True)
            for key, value in llm_dict.items():
                if isinstance(value, str):
                    toml_content += f'{key} = "{value}"\n'
                elif isinstance(value, bool):
                    toml_content += f"{key} = {str(value).lower()}\n"
                else:
                    toml_content += f"{key} = {value}\n"
        
        # 处理浏览器配置
        if config_data.browser:
            toml_content += "\n# Browser configuration\n[browser]\n"
            browser_dict = config_data.browser.dict(exclude_none=True, exclude={"proxy"})
            
            # 处理主要浏览器配置（不含proxy部分）
            for key, value in browser_dict.items():
                if isinstance(value, str):
                    toml_content += f'{key} = "{value}"\n'
                elif isinstance(value, bool):
                    toml_content += f"{key} = {str(value).lower()}\n"
                elif isinstance(value, list):
                    value_str = str(value).replace("'", '"')
                    toml_content += f"{key} = {value_str}\n"
                else:
                    toml_content += f"{key} = {value}\n"
            
            # 处理代理配置
            print("browser:",config_data.browser)
            if hasattr(config_data.browser, 'proxy') and config_data.browser.proxy:
                toml_content += "\n# Proxy settings for the browser\n[browser.proxy]\n"
                proxy_dict = config_data.browser.proxy.dict(exclude_none=True)
                print("proxy:",proxy_dict)
                for key, value in proxy_dict.items():
                    if value:  # 仅添加非空值
                        toml_content += f'{key} = "{value}"\n'
        
        # 处理搜索配置
        if config_data.search:
            toml_content += "\n# Search settings\n[search]\n"
            search_dict = config_data.search.dict(exclude_none=True)
            for key, value in search_dict.items():
                if isinstance(value, str):
                    toml_content += f'{key} = "{value}"\n'
                elif isinstance(value, bool):
                    toml_content += f"{key} = {str(value).lower()}\n"
                elif isinstance(value, list):
                    value_str = str(value).replace("'", '"')
                    toml_content += f"{key} = {value_str}\n"
                else:
                    toml_content += f"{key} = {value}\n"
        
        # 写入配置文件
        with open(config_path, "w", encoding="utf-8") as f:
            f.write(toml_content)
        
        # 重新加载配置
        app_config.reload_config()
        
        return {"status": "success"}
    except Exception as e:
        raise HTTPException(status_code=401, detail="错误的参数："+ e)
    
@router.get("/tasks")
async def get_tasks():
    sorted_tasks = sorted(
        task_manager.tasks.values(), key=lambda task: task.created_at, reverse=True
    )
    return JSONResponse(
        content=[task.model_dump() for task in sorted_tasks],
        headers={"Content-Type": "application/json"},
    )


